<?php

/**
 * This is the model class for table "gs_user".
 *
 * The followings are the available columns in table 'gs_user':
 * @property integer $id
 * @property integer $deja_id
 * @property string $device
 * @property double $game_money
 * @property double $real_money
 * @property integer $final_stage
 * @property string $higest_score
 * @property integer $rank
 * @property string $user_name
 * @property integer $flag
 * @property string $create_time
 * @property string $others
 */
class User extends CActiveRecord
{
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return User the static model class
     */
    //type==0:game_money;type==1:real_money

    public function hasEnoughItem($item)
    {
        $result = false;
        if (isset($this->others)) {
            if (is_object($this->others) || is_array($this->others)) {
                $uOthers = $this->others;
            } else {
                $uOthers = json_decode($this->others);
            }
            if (isset($uOthers->items) && is_array($uOthers->items)) {
                foreach ($uOthers->items as $itemT) {
                    if ($itemT->itemId == $item->itemId && $itemT->type == $item->type) {
                        if ($itemT->count >= $item->count) {
                            $result = true;
                        }
                    }
                }
            }
        }
        return $result;
    }

    public function exhaustItem($item)
    {
        $uOthers = new StdClass;
        if (is_object($this->others) || is_array($this->others)) {
            $uOthers = $this->others;
        } else {
            $uOthers = json_decode($this->others);
        }
        foreach ($uOthers->items as $itemT) {
            if ($itemT->itemId == $item->itemId && $itemT->type == $item->type) {
                $itemT->count = $itemT->count - $item->count;
                $this->others = json_encode($uOthers);
                $this->higest_score = json_encode($this->higest_score);
                $this->save();
                $this->higest_score = json_decode($this->higest_score);
                $this->others = json_decode($this->others);
                $uProperty = $this->attributes;
                array_walk_recursive($uProperty, function (&$item, $key) {
                    if (is_numeric($item)) {
                        $item = (int)$item;
                    }
                });
                UserService::getInstance()->updateDeviceUKey($this->device, json_encode($uProperty));
            }
        }
        return $uProperty;
    }

    public function buyItem($itemId, $type, $buyType, $count = 1,$receipt=null)
    {
        //-1 not enough money ;-2 item not find;-3 bundleId not find;-4 verify fail;
        $price = 0;
        $priceT = 0;
        $verify_id = 0;
        $item = ItemService::getInstance()->findItem($itemId, $type);
        if (isset($item)) {
            if ($buyType == ItemBuyTypeEnum::game_money) {
                $price = $item->game_money * $count;
                if ($this->game_money > $price) {
                    $this->game_money -= $price;
                } else {
                    return -1;
                }
            } else if ($buyType == ItemBuyTypeEnum::real_money) {
                $priceT = $item->real_money * $count;
                if ($this->real_money > $priceT) {
                    $this->real_money -= $priceT;
                } else {
                    return -1;
                }
            }
            $bundleId = null;
            if($buyType == ItemBuyTypeEnum::cash)
            {
                $itemPro = $item->properties;
                if(is_string($itemPro))
                {
                    $itemPro = json_decode($itemPro);
                }
                if(isset($itemPro) && isset($itemPro->bundleId))
                {
                    $bundleId = $itemPro->bundleId;
                }else
                {
                    return -3;
                }
                $api_return = ShooterService::getInstance()->verifyReceipt($receipt);
                if(!isset($api_return))
                {
                    return -4;
                }
                if($api_return->status == 0)
                {
                    $verifyObj = new Verify();
                    $verifyObj->verify_code = $receipt;
                    $verifyObj->app_id="shooter";
                    $verifyObj->bundle_id = $bundleId;
                    $verifyObj->receipt = json_encode($api_return->receipt);
                    $verifyObj->save();
                    $verify_id = $verifyObj->id;
                }else
                {
                    return -4;
                }
            }
            $uOthers = new StdClass;
            if (isset($this->others)) {
                if (is_object($this->others) || is_array($this->others)) {
                    $uOthers = $this->others;
                } else {
                    $uOthers = json_decode($this->others);
                }
            }
            if (!isset($uOthers->items)) {
                $uOthers->items = array();
            }
            $oldItem = false;
            foreach ($uOthers->items as $itemT) {
                if ($itemT->itemId == (int)$itemId && $itemT->type == (int)$type) {
                    $oldItem = true;
                    $itemT->count = $itemT->count + $count;
                }
            }

            if (!$oldItem) {
                $object = new StdClass;
                $object->itemId = (int)$itemId;
                $object->type = (int)$type;
                $object->count = $count;
                array_push($uOthers->items, $object);
            }
            $this->others = json_encode($uOthers);
            $this->higest_score = json_encode($this->higest_score);
            $this->save();

            //update cache
            $this->higest_score = json_decode($this->higest_score);
            $this->others = json_decode($this->others);
            $uProperty = $this->attributes;
            array_walk_recursive($uProperty, function (&$item, $key) {
                if (is_numeric($item)) {
                    $item = (int)$item;
                }
            });
            UserService::getInstance()->updateDeviceUKey($this->device, json_encode($uProperty));

            $bhObj = new BuyHistory();
            date_default_timezone_set('UTC');
            $bhObj->create_time = date('Y-m-d H:i:s', time());
            $bhObj->user_id = $this->id;
            if (isset($this->deja_id) && $this->deja_id > 0) {
                $bhObj->deja_id = $this->deja_id;
            }
            $bhObj->device = $this->device;
            $bhObj->item_id = $itemId;
            if ($buyType == ItemBuyTypeEnum::game_money) {
                $bhObj->game_money = $price;
            } else if ($buyType == ItemBuyTypeEnum::real_money) {
                $bhObj->real_money = $priceT;
            }
            $bhObj->version = $item->version;
            $bhObj->type = $type;
            $bhObj->count = $count;
            $bhObj->verify_id = $verify_id;
            $bhObj->save();
            return 0;
        } else {
            return -2;
        }
    }

    protected function afterFind()
    {
        parent::afterFind();
        // in the following line i'm just making $valueModified and $value equal, but obviously you would have to insert the 2 decimals
        $this->higest_score = json_decode($this->higest_score);
        $this->others = json_decode($this->others);
    }

    protected  function beforeSave() {
        if(!isset($this->others))
        {
            $this->others = "";
        }
        if(!is_string($this->others))
        {
            $this->others = json_encode($this->others);
        }
        if(!isset($this->higest_score))
        {
            $this->higest_score = "";
        }
        if(!is_string($this->higest_score))
        {
            $this->higest_score = json_encode($this->higest_score);
        }
        return parent::beforeSave();
    }


    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'gs_user';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('user_name', 'required'),
            array('deja_id, final_stage, rank, flag', 'numerical', 'integerOnly' => true),
            array('game_money, real_money', 'numerical'),
            array('device, user_name', 'length', 'max' => 255),
            array('higest_score, create_time, others', 'safe'),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, deja_id, device, game_money, real_money, final_stage, higest_score, rank, user_name, flag, create_time, others', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array();
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'deja_id' => 'Deja',
            'device' => 'Device',
            'game_money' => 'Game Money',
            'real_money' => 'Real Money',
            'final_stage' => 'Final Stage',
            'higest_score' => 'Higest Score',
            'rank' => 'Rank',
            'user_name' => 'User Name',
            'flag' => 'Flag',
            'create_time' => 'Create Time',
            'others' => 'Others',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('deja_id', $this->deja_id);
        $criteria->compare('device', $this->device, true);
        $criteria->compare('game_money', $this->game_money);
        $criteria->compare('real_money', $this->real_money);
        $criteria->compare('final_stage', $this->final_stage);
        $criteria->compare('higest_score', $this->higest_score, true);
        $criteria->compare('rank', $this->rank);
        $criteria->compare('user_name', $this->user_name, true);
        $criteria->compare('flag', $this->flag);
        $criteria->compare('create_time', $this->create_time, true);
        $criteria->compare('others', $this->others, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }
}